#include "WidgetOvertake.hpp"


WidgetOvertake::WidgetOvertake(const char *pRootPath, const char *pIniUIFilename, const char *pIniDriverMappingFilename, const char *pIniVehiculeClassMappingFilename)
{
	initialized = false;
	rootPath = pRootPath; 

	nbProfiles = GetPrivateProfileInt("Profiles", "count", 0, pIniUIFilename);
	for (int i = 0 ; i < nbProfiles; i++) {
		sprintf(tmp, "Profile.%d", (i+1));
		profiles[i].widgetOffsetX = (signed int)GetPrivateProfileInt(tmp, "Overtake.offsetX", 0, pIniUIFilename);
		profiles[i].widgetOffsetY = (signed int)GetPrivateProfileInt(tmp, "Overtake.offsetY", 0, pIniUIFilename);
		profiles[i].hide = GetPrivateProfileInt(tmp, "Overtake.hide", 0, pIniUIFilename) != 0;
	}

	//std::string str = rootPath;
	GetPrivateProfileString("UI Widgets", "Overtake.ini", "", tmp, 999, pIniUIFilename);
	//str.append(tmp);
	sprintf(iniUIFilename, "%s%s", rootPath, tmp);
	//iniUIFilename = str.c_str(); //pIniUIFilename; 
	available = GetPrivateProfileInt("Overtake", "available", 0, iniUIFilename) != 0;

	nbEvent = 0;
}

void WidgetOvertake::init(const ScreenInfoV01 &info, float ratio, float ratioWidth, float ratioHeight, Sprite spriteList[]) {
	if (!available) {
		initialized = true;
		return;
	}
	eventBufferSize =  GetPrivateProfileInt("Overtake", "max.overtake.bufferized", 2, iniUIFilename) + 1; // 3 overtake event max by default (1 running and 2 bufferized)
	inhibitionDelay = GetPrivateProfileInt("Overtake", "inhibition.duration", 0, iniUIFilename);
	animRayonSize = (int)(10 * ratioWidth);
	secondOfBeforeAnimation = ((double)GetPrivateProfileInt("Overtake", "millisecond.before.animation", 500, iniUIFilename))/1000;
	secondForAnimation = ((double)GetPrivateProfileInt("Overtake", "millisecond.for.animation", 1000, iniUIFilename))/1000;
	secondOfAfterAnimation = ((double)GetPrivateProfileInt("Overtake", "millisecond.after.animation", 500, iniUIFilename))/1000;

	for (int i = 0 ; i < nbProfiles; i++) {
		profiles[i].widgetOffsetX *= ratioWidth;
		profiles[i].widgetOffsetY *= ratioHeight;
	}

	int posX = (int)(ratioWidth * GetPrivateProfileInt("Overtake", "image.left", 40, iniUIFilename));//40;
	int posY = (int)(ratioHeight * GetPrivateProfileInt("Overtake", "image.top", 550, iniUIFilename));//550;

	//LPDIRECT3DDEVICE9 dev = static_cast<LPDIRECT3DDEVICE9>(info.mDevice);	
	

	bgImageData.spriteIndex = GetPrivateProfileInt("Overtake", "image.id", 0, iniUIFilename) -1;
	if (bgImageData.spriteIndex > -1) {
		bgImageData.left = posX;
		bgImageData.top = posY;
		bgImageData.width = (int)(GetPrivateProfileInt("Overtake", "image.width", (int)spriteList[bgImageData.spriteIndex].width, iniUIFilename) * ratioWidth);
		bgImageData.height = (int)(GetPrivateProfileInt("Overtake", "image.height", (int)spriteList[bgImageData.spriteIndex].height, iniUIFilename) * ratioHeight);
		bgImageData.colorIndex = GetPrivateProfileInt("Overtake", "image.color.id", 1, iniUIFilename) -1;
	}
	frontPlaceAvailable = GetPrivateProfileInt("Overtake.FrontPlace", "available", 0, iniUIFilename) != 0;
	if (frontPlaceAvailable) {
		frontPlaceTextData.fontIndex = GetPrivateProfileInt("Overtake.FrontPlace", "text.font.id", 1, iniUIFilename) - 1;
		frontPlaceTextData.colorIndex = GetPrivateProfileInt("Overtake.FrontPlace", "text.font.color.id", 1, iniUIFilename) - 1;
		frontPlaceTextData.rect.left = (int)(posX + GetPrivateProfileInt("Overtake.FrontPlace", "text.left", 0, iniUIFilename) * ratioWidth);
		frontPlaceTextData.rect.top = (int)(posY + GetPrivateProfileInt("Overtake.FrontPlace", "text.top", 0, iniUIFilename) * ratioHeight);
		frontPlaceTextData.rect.right = (int)(posX + GetPrivateProfileInt("Overtake.FrontPlace", "text.right", 100, iniUIFilename) * ratioWidth);
		frontPlaceTextData.rect.bottom = (int)(posY + GetPrivateProfileInt("Overtake.FrontPlace", "text.bottom", 100, iniUIFilename) * ratioHeight);
		frontPlaceTextData.alignment = GetPrivateProfileInt("Overtake.FrontPlace", "text.alignment", 1, iniUIFilename);
	}
	backPlaceAvailable = GetPrivateProfileInt("Overtake.BackPlace", "available", 0, iniUIFilename) != 0;
	if (backPlaceAvailable) {
		backPlaceTextData.fontIndex = GetPrivateProfileInt("Overtake.BackPlace", "text.font.id", 1, iniUIFilename) - 1;
		backPlaceTextData.colorIndex = GetPrivateProfileInt("Overtake.BackPlace", "text.font.color.id", 1, iniUIFilename) - 1;
		backPlaceTextData.rect.left = (int)(posX + GetPrivateProfileInt("Overtake.BackPlace", "text.left", 0, iniUIFilename) * ratioWidth);
		backPlaceTextData.rect.top = (int)(posY + GetPrivateProfileInt("Overtake.BackPlace", "text.top", 0, iniUIFilename) * ratioHeight);
		backPlaceTextData.rect.right = (int)(posX + GetPrivateProfileInt("Overtake.BackPlace", "text.right", 100, iniUIFilename) * ratioWidth);
		backPlaceTextData.rect.bottom = (int)(posY + GetPrivateProfileInt("Overtake.BackPlace", "text.bottom", 100, iniUIFilename) * ratioHeight);
		backPlaceTextData.alignment = GetPrivateProfileInt("Overtake.BackPlace", "text.alignment", 1, iniUIFilename);
	}

	looserNameAvailable = GetPrivateProfileInt("Overtake.Looser", "available", 0, iniUIFilename) != 0;
	if (looserNameAvailable) {
		looserNameTextData.rect.left = (int)(posX + GetPrivateProfileInt("Overtake.Looser", "text.left", 0, iniUIFilename) * ratioWidth);
		looserNameTextData.rect.top = (int)(posY + GetPrivateProfileInt("Overtake.Looser", "text.top", 0, iniUIFilename) * ratioHeight);
		looserNameTextData.rect.right = (int)(posX + GetPrivateProfileInt("Overtake.Looser", "text.right", 100, iniUIFilename) * ratioWidth);
		looserNameTextData.rect.bottom = (int)(posY + GetPrivateProfileInt("Overtake.Looser", "text.bottom", 100, iniUIFilename) * ratioHeight);

		looserNameTextData.fontIndex = GetPrivateProfileInt("Overtake.Looser", "text.font.id", 1, iniUIFilename) - 1;
		looserNameTextData.colorIndex = GetPrivateProfileInt("Overtake.Looser", "text.font.color.id", 1, iniUIFilename) - 1;
		looserNameTextData.alignment = GetPrivateProfileInt("Overtake.Looser", "text.alignment", 1, iniUIFilename);

		looserNameImageData.spriteIndex = GetPrivateProfileInt("Overtake.Looser", "image.id", 0, iniUIFilename) -1;
		if (looserNameImageData.spriteIndex != -1) {
			looserNameImageData.left = (int)(posX + GetPrivateProfileInt("Overtake.Looser", "image.left", 0, iniUIFilename) * ratioWidth);
			looserNameImageData.top = (int)(posY + GetPrivateProfileInt("Overtake.Looser", "image.top", 0, iniUIFilename) * ratioHeight);
			looserNameImageData.width = (int)(GetPrivateProfileInt("Overtake.Looser", "image.width", (int)spriteList[looserNameImageData.spriteIndex].width, iniUIFilename) * ratioWidth);
			looserNameImageData.height = (int)(GetPrivateProfileInt("Overtake.Looser", "image.height", (int)spriteList[looserNameImageData.spriteIndex].height, iniUIFilename) * ratioHeight);
			looserNameImageData.colorIndex = GetPrivateProfileInt("Overtake.Looser", "image.color.id", 1, iniUIFilename) -1;
		}
	}

	winnerNameAvailable = GetPrivateProfileInt("Overtake.Winner", "available", 0, iniUIFilename) != 0;
	if (winnerNameAvailable) {
		winnerNameTextData.rect.left = (int)(posX + GetPrivateProfileInt("Overtake.Winner", "text.left", 0, iniUIFilename) * ratioWidth);
		winnerNameTextData.rect.top = (int)(posY + GetPrivateProfileInt("Overtake.Winner", "text.top", 0, iniUIFilename) * ratioHeight);
		winnerNameTextData.rect.right = (int)(posX + GetPrivateProfileInt("Overtake.Winner", "text.right", 100, iniUIFilename) * ratioWidth);
		winnerNameTextData.rect.bottom = (int)(posY + GetPrivateProfileInt("Overtake.Winner", "text.bottom", 100, iniUIFilename) * ratioHeight);

		winnerNameTextData.fontIndex = GetPrivateProfileInt("Overtake.Winner", "text.font.id", 1, iniUIFilename) - 1;
		winnerNameTextData.colorIndex = GetPrivateProfileInt("Overtake.Winner", "text.font.color.id", 1, iniUIFilename) - 1;
		winnerNameTextData.alignment = GetPrivateProfileInt("Overtake.Winner", "text.alignment", 1, iniUIFilename);

		winnerNameImageData.spriteIndex = GetPrivateProfileInt("Overtake.Winner", "image.id", 0, iniUIFilename) -1;
		if (winnerNameImageData.spriteIndex != -1) {
			winnerNameImageData.left = (int)(posX + GetPrivateProfileInt("Overtake.Winner", "image.left", 0, iniUIFilename) * ratioWidth);
			winnerNameImageData.top = (int)(posY + GetPrivateProfileInt("Overtake.Winner", "image.top", 0, iniUIFilename) * ratioHeight);
			winnerNameImageData.width = (int)(GetPrivateProfileInt("Overtake.Winner", "image.width", (int)spriteList[looserNameImageData.spriteIndex].width, iniUIFilename) * ratioWidth);
			winnerNameImageData.height = (int)(GetPrivateProfileInt("Overtake.Winner", "image.height", (int)spriteList[looserNameImageData.spriteIndex].height, iniUIFilename) * ratioHeight);
			winnerNameImageData.colorIndex = GetPrivateProfileInt("Overtake.Winner", "image.color.id", 1, iniUIFilename) -1;
		}
	}

}

void WidgetOvertake::updateData(double mET) {
	if (nbEvent > 0) {
		if (!playingEvent) {
			startEventET = mET;
			sprintf(frontPlace, "%d", eventList[0].newWinnerPlace);
			sprintf(backPlace, "%d", eventList[0].oldWinnerPlace);
			currentReplayET = eventList[0].overtakeET;
			idToViewInReplay = eventList[0].winnerIDToReplay;
			playingEvent = true;
		} else if (mET - startEventET >= secondOfBeforeAnimation && mET - startEventET <= secondOfBeforeAnimation + secondForAnimation ) {
			sprintf(backPlace, "%d", (eventList[0].newWinnerPlace + 1));
		} else if (mET - startEventET >= secondOfBeforeAnimation + secondForAnimation && mET - startEventET <= secondOfBeforeAnimation + secondForAnimation + secondOfAfterAnimation ) {
		} else if (mET - startEventET > secondOfBeforeAnimation + secondForAnimation + secondOfAfterAnimation) {
			playingEvent = false;
			if (nbEvent > 1) {
				for (int i = 1; i < nbEvent; i++) {
					memcpy(&eventList[i - 1].looserName, &eventList[i].looserName, 32);
					memcpy(&eventList[i - 1].winnerName, &eventList[i].winnerName, 32);
					memcpy(&eventList[i - 1].newWinnerPlace, &eventList[i].newWinnerPlace, 1);
					memcpy(&eventList[i - 1].oldWinnerPlace, &eventList[i].oldWinnerPlace, 1);
				}
			}
			nbEvent --;
		}
	}
}

void WidgetOvertake::addEvent(double mET, DriverInfo & looserDi, DriverInfo & winnerDi, unsigned char oldWinnerPlace, unsigned char newWinnerPlace, double overtakeET) {
	if (mET <= inhibitionDelay) return;
	if (nbEvent >= eventBufferSize) return; // buffer full

	eventList[nbEvent].oldWinnerPlace = oldWinnerPlace;
	eventList[nbEvent].newWinnerPlace = newWinnerPlace;
	memcpy(&eventList[nbEvent].looserName, looserDi.mDriverName, 32);
	memcpy(&eventList[nbEvent].winnerName, winnerDi.mDriverName, 32);
	eventList[nbEvent].overtakeET = overtakeET;
	eventList[nbEvent].winnerIDToReplay = winnerDi.mID;
	
	nbEvent++;
}

void WidgetOvertake::render(int profileIndex, const ScreenInfoV01 &info, const LPD3DXFONT *fontList, const D3DCOLOR *colorList, Sprite spriteList[], double mET) { 
	if (!available) return;
		if (gReplayIsActive) return;
	if (!playingEvent) return;
	if (profiles[profileIndex].hide) return;

	LPDIRECT3DDEVICE9 dev = static_cast<LPDIRECT3DDEVICE9>(info.mDevice);	
	if (bgImageData.spriteIndex > -1) {
		spriteList[bgImageData.spriteIndex].setPosition(bgImageData.left + profiles[profileIndex].widgetOffsetX, bgImageData.top + profiles[profileIndex].widgetOffsetY);
		spriteList[bgImageData.spriteIndex].setSize(bgImageData.width, bgImageData.height);
		spriteList[bgImageData.spriteIndex].render(dev, colorList[bgImageData.colorIndex], 100);
	}
	if (frontPlaceAvailable) {
		tmpRect.left = frontPlaceTextData.rect.left + profiles[profileIndex].widgetOffsetX;
		tmpRect.top = frontPlaceTextData.rect.top + profiles[profileIndex].widgetOffsetY;
		tmpRect.right = frontPlaceTextData.rect.right + profiles[profileIndex].widgetOffsetX;
		tmpRect.bottom = frontPlaceTextData.rect.bottom + profiles[profileIndex].widgetOffsetY;
		fontList[frontPlaceTextData.fontIndex]->DrawTextA(NULL, frontPlace, -1, &tmpRect, frontPlaceTextData.alignment, colorList[frontPlaceTextData.colorIndex]);
	}
	if (backPlaceAvailable) {
		tmpRect.left = backPlaceTextData.rect.left + profiles[profileIndex].widgetOffsetX;
		tmpRect.top = backPlaceTextData.rect.top + profiles[profileIndex].widgetOffsetY;
		tmpRect.right = backPlaceTextData.rect.right + profiles[profileIndex].widgetOffsetX;
		tmpRect.bottom = backPlaceTextData.rect.bottom + profiles[profileIndex].widgetOffsetY;
		fontList[backPlaceTextData.fontIndex]->DrawTextA(NULL, backPlace, -1, &tmpRect, backPlaceTextData.alignment, colorList[backPlaceTextData.colorIndex]);
	}

	// anim looser
	double delta = 0;
	if (mET - startEventET >= secondOfBeforeAnimation && mET - startEventET <= secondOfBeforeAnimation + secondForAnimation) {
		delta = (mET - startEventET - secondOfBeforeAnimation) / secondForAnimation;
	} else if (mET - startEventET > secondOfBeforeAnimation + secondForAnimation ) {
		delta = 1;
	}
//	animLooserOffsetX = (int)((sin(3.14159 * delta) * animRayonSize)  + (winnerNameTextData.rect.left - looserNameTextData.rect.left) * delta) ;
	animLooserOffsetX = (int)((winnerNameTextData.rect.left - looserNameTextData.rect.left) * delta) ;
	animLooserOffsetY = (int)((winnerNameTextData.rect.top - looserNameTextData.rect.top) * delta) ;

	if (looserNameAvailable) {
		if (looserNameImageData.spriteIndex != -1) {
			spriteList[looserNameImageData.spriteIndex].setPosition(looserNameImageData.left + profiles[profileIndex].widgetOffsetX + animLooserOffsetX, looserNameImageData.top + profiles[profileIndex].widgetOffsetY + animLooserOffsetY);
			spriteList[looserNameImageData.spriteIndex].setSize(looserNameImageData.width, looserNameImageData.height);
			spriteList[looserNameImageData.spriteIndex].render(dev, colorList[looserNameImageData.colorIndex], 100);
		}
		tmpRect.left = looserNameTextData.rect.left + profiles[profileIndex].widgetOffsetX + animLooserOffsetX;
		tmpRect.top = looserNameTextData.rect.top + profiles[profileIndex].widgetOffsetY + animLooserOffsetY;
		tmpRect.right = looserNameTextData.rect.right + profiles[profileIndex].widgetOffsetX + animLooserOffsetX;
		tmpRect.bottom = looserNameTextData.rect.bottom + profiles[profileIndex].widgetOffsetY + animLooserOffsetY;
		fontList[looserNameTextData.fontIndex]->DrawTextA(NULL, eventList[0].looserName, -1, &tmpRect, looserNameTextData.alignment, colorList[looserNameTextData.colorIndex]);
	}

	// anim winner
	delta = 0;
	if (mET - startEventET >= secondOfBeforeAnimation && mET - startEventET <= secondOfBeforeAnimation + secondForAnimation ) {
		delta = (mET - startEventET - secondOfBeforeAnimation) / secondForAnimation;
	} else if (mET - startEventET > secondOfBeforeAnimation + secondForAnimation ) {
		delta = 1;
	}
	animWinnerOffsetX = (int)((sin(3.14159 * delta) * animRayonSize)  + (looserNameTextData.rect.left - winnerNameTextData.rect.left) * delta) ;
	animWinnerOffsetY = (int)((looserNameTextData.rect.top - winnerNameTextData.rect.top) * delta) ;

	if (winnerNameAvailable) {
		if (winnerNameImageData.spriteIndex != -1) {
			spriteList[winnerNameImageData.spriteIndex].setPosition(winnerNameImageData.left + profiles[profileIndex].widgetOffsetX + animWinnerOffsetX, winnerNameImageData.top + profiles[profileIndex].widgetOffsetY + animWinnerOffsetY);
			spriteList[winnerNameImageData.spriteIndex].setSize(winnerNameImageData.width, winnerNameImageData.height);
			spriteList[winnerNameImageData.spriteIndex].render(dev, colorList[winnerNameImageData.colorIndex], 100);
		}
		tmpRect.left = winnerNameTextData.rect.left + profiles[profileIndex].widgetOffsetX + animWinnerOffsetX;
		tmpRect.top = winnerNameTextData.rect.top + profiles[profileIndex].widgetOffsetY + animWinnerOffsetY;
		tmpRect.right = winnerNameTextData.rect.right + profiles[profileIndex].widgetOffsetX + animWinnerOffsetX;
		tmpRect.bottom = winnerNameTextData.rect.bottom + profiles[profileIndex].widgetOffsetY + animWinnerOffsetY;
		fontList[winnerNameTextData.fontIndex]->DrawTextA(NULL, eventList[0].winnerName, -1, &tmpRect, winnerNameTextData.alignment, colorList[winnerNameTextData.colorIndex]);
	}

}
 


WidgetOvertake::~WidgetOvertake(void)
{
}
